﻿
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Protocol.SouthGridProtocol.Blocks;
using Protocol.SouthGridProtocol.Decoder;
using Protocol.SouthGridProtocol.Encoder;
using PacoToolKit.Format;
namespace Protocol.SouthGridProtocol.Model
{
    public class C13H
    {
        private static string afn = "13";
        private static string head = "68";
        private static string bottom = "16";

        private static Seq seq = new Seq(0, 1, 1, 1, 9);
        private static C c = new C(0, 1, 1, null, 0, 11);//prm=1,funcode=11

        public static Hashtable nameHashTable = new Hashtable { 
            //{"E200003E","时钟异常报警"},
            //{"E2000035","电能表编程时间更改"},
            //{"E2000033","终端停电"},
            //{"E200002E","电能表停走"},
            //{"E2000016","电表失压"},
            //{"E200000D","潮流反向"},
            //{"E2000036","时段费率更改"},
            //{"E200002C","示度下降"},
            //{"E200003D","通讯失败"},
            //{"E200003C","电表拉闸控制失败"},
            //{"E200003B","集中器继电器告警"},
            //{"E200002B","剩余电费不足"},
            //{"E200003A","月流量超限"}

            {"E2000001","计量装置门开闭"},
            {"E2000002","电流反极性"},
            {"E2000003","电压逆相序"},
            {"E2000004","电流不平衡"},
            {"E2000005","电压不平衡"},
            {"E2000006","零序电流偏大"},
            {"E2000007","A 相 CT 二次侧短路"},
            {"E2000008","B 相 CT 二次侧短路"},
            {"E2000009","C 相 CT 二次侧短路"},
            {"E200000A","A 相 CT 二次侧开路"},
            {"E200000B","B 相 CT 二次侧开路"},
            {"E200000C","C 相 CT 二次侧开路"},
            {"E200000D","A 相潮流反向"},
            {"E200000E","B 相潮流反向"},
            {"E200000F","C 相潮流反向"},
            {"E2000010","A 相电流过流"},
            {"E2000011","B 相电流过流"},
            {"E2000012","C 相电流过流"},
            {"E2000013","A 相电流失流"},
            {"E2000014","B 相电流失流"},
            {"E2000015","C 相电流失流"},
            {"E2000016","A 相电压失压"},
            {"E2000017","B 相电压失压"},
            {"E2000018","C 相电压失压"},
            {"E2000019","全失压"},
            {"E200001A","A 相电压过压"},
            {"E200001B","B 相电压过压"},
            {"E200001C","C 相电压过压"},
            {"E200001D","A 相电压断相"},
            {"E200001E","B 相电压断相"},
            {"E200001F","C 相电压断相"},
            //
            {"E2000020","A 相电压畸变"},
            {"E2000021","B 相电压畸变"},
            {"E2000022","C 相电压畸变"},
            {"E2000023","A 相电流畸变"},
            {"E2000024","B 相电流畸变"},
            {"E2000025","C 相电流畸变"},
            //
            {"E2000026","无功过补偿"},
            {"E2000027","无功欠补偿"},
            {"E2000028","功率超定值"},
            {"E2000029","负荷过载"},
            {"E200002A","超合同容量用电"},
            //
            {"E200002B","剩余电费不足"},
            //
            {"E200002C","示度下降"},
            {"E200002D","电能表飞走"},
            //
            {"E200002E","电能表停走"},
            //
            {"E200002F","电能表通讯失败"},
            //
            {"E2000030","差动告警"},
            //
            {"E2000031","最大需量手动复零"},
            //
            {"E2000032","时钟电池电压过低"},
            //
            {"E2000033","终端掉电"},
            {"E2000034","终端上电"},
            {"E2000035","电能表编程时间更改"},
            //
            {"E2000036","电能表时段或费率更改"},
            //
            {"E2000037","电能表脉冲常数更改"},
            //
            {"E2000038","电能表的互感器倍率更改"},
            //
            {"E2000039","遥信变位"},
            //
            {"E200003A","月通信流量越限"},
            //
            {"E200003B","继电器变位"},
            {"E200003C","电能表拉合闸失败"},
            //
            {"E200003D","抄表失败"},
            //
            {"E200003E","电能表时钟异常"},
            //
            {"E200003F","电能表校时失败"},
            //
            {"E2000040","电能表 A、B、C 相失压总次数"},
            {"E2000041","电能表 A、B、C 相失流总次数"},
            {"E2000042","电能表 A、B、C 相潮流反向总次数"},
            //
            {"E2000043","电能表编程总次数"},
            //
            {"E2000044","A 相电压偏差越限"},
            {"E2000045","B 相电压偏差越限"},
            {"E2000046","C 相电压偏差越限"},
            {"E2000047","频率偏差越限"},
            {"E2000048","A 相闪变越限"},
            {"E2000049","B 相闪变越限"},
            {"E200004A","C 相闪变越限"},
            {"E200004B","电压不平衡越限"},
            //
            //{"E200004C",},
            {"E200004D","表端钮盒开启告警"},
            {"E200004E","表盖开启告警"}
        };

        #region DI 长度索引表
        public static Hashtable lenHashTable = new Hashtable {
            {"E2000001",91},{"E2000002",91},{"E2000003",91},{"E2000004",91},{"E2000005",91},
            {"E2000006",91},{"E2000007",91},{"E2000008",91},{"E2000009",91},{"E200000A",91},
            {"E200000B",91},{"E200000C",91},{"E200000D",91},{"E200000E",91},{"E200000F",91},
            {"E2000010",91},{"E2000011",91},{"E2000012",91},{"E2000013",91},{"E2000014",91},
            {"E2000015",91},{"E2000016",91},{"E2000017",91},{"E2000018",91},{"E2000019",91},
            {"E200001A",91},{"E200001B",91},{"E200001C",91},{"E200001D",91},{"E200001E",91},
            {"E200001F",91},
            //
            {"E2000020",32},{"E2000021",32},{"E2000022",32},{"E2000023",32},{"E2000024",32},{"E2000025",32},
            //
            {"E2000026",91},{"E2000027",91},{"E2000028",91},{"E2000029",91},{"E200002A",91},
            //
            {"E200002B",27},
            //
            {"E200002C",159},{"E200002D",159},
            //
            {"E200002E",91},
            //
            {"E200002F",7},
            //
            {"E2000030",159},
            //
            {"E2000031",55},
            //
            {"E2000032",7},
            //
            {"E2000033",91},{"E2000034",91},{"E2000035",91},
            //
            {"E2000036",7},
            //
            {"E2000037",35},
            //
            {"E2000038",31},
            //
            {"E2000039",37},
            //
            {"E200003A",10},
            //
            {"E200003B",9},{"E200003C",9},
            //
            {"E200003D",263},
            //
            {"E200003E",20},
            //
            {"E200003F",7},
            //
            {"E2000040",25},{"E2000041",25},{"E2000042",25},
            //
            {"E2000043",10},
            //
            {"E2000044",32},{"E2000045",32},{"E2000046",32},{"E2000047",32},
            {"E2000048",32},{"E2000049",32},{"E200004A",32},{"E200004B",32},
            //
            //{"E200004C",},
            {"E200004D",55},{"E200004E",55}
            //{"E20010FF",25},{"E200FFFF",25},
        };
        #endregion


        public static string encodeC13H(string concentrator, List<C13HData> dataList)
        {
            //主站启动的发送帧的MSA应为非零值,终端启动发送帧的MSA应为零，其主站响应帧的MSA也应为零
            concentrator = concentrator.Substring(0, 12) + "01";

            StringBuilder sb = new StringBuilder();
            foreach (C13HData data in dataList)
            {
                sb.Append(data.da); sb.Append(data.di); sb.Append(data.beginTime); sb.Append(data.endTime);
            }
            StringBuilder msgsb = new StringBuilder();
            string length = BaseEncoder.CalcLength(c.encodeC() + concentrator + afn + seq.encodeSeqString() + sb.ToString());
            string cs = BaseEncoder.CalcCSCode(c.encodeC() + concentrator + afn + seq.encodeSeqString() + sb.ToString());
            return head + length + length + head + c.encodeC() + concentrator + afn + seq.encodeSeqString() + sb.ToString() + cs + bottom;
        }

        public static List<CData> decodeC13H(string msg)
        {
            List<CData> dataList = new List<CData>();
            int msgLength = BaseDecoder.GetLength(msg);//字节数
            int dataRemainLen = (msgLength - 10) * 2;//初始 剩余未读数据长度
            string dataRemain = msg.Substring(32, dataRemainLen);//初始 剩余未读数据
            //循环读取块
            while (dataRemainLen >= 12)
            {
                string da = dataRemain.Substring(0, 4);
                string di = Formater.ReverseHexString(dataRemain.Substring(4, 8));
                int currentDataBlockLength = (int)lenHashTable[di];
                string data = dataRemain.Substring(12, currentDataBlockLength * 2);

                dataList.Add(new CData { da = da, di = di, data = data });//读完一块，加入列表

                //重新计算剩余未读数据
                dataRemain = dataRemain.Remove(0, (4 + 8 + currentDataBlockLength * 2));
                dataRemainLen = dataRemain.Length;
            }

            return dataList;
        }

    }
}
